package org.jhulk.tests;

/**
 * Bugs:
 * - Extra clicks for unit placement, if 4 units it takes 5 clicks to end unit placement phase
 * -- determined it was a bug in the loop that looks for unplaced units
 */

import java.util.ArrayList;

import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.XMLPackedSheet;
import org.newdawn.slick.tiled.TiledMap;
import org.jhulk.sprites.Marine;
import org.jhulk.sprites.Squad;
import org.jhulk.utils.GameUtils;
import org.jhulk.utils.MapTile;
import org.jhulk.utils.TileMapUtils;

public class UnitPlacementTest extends BasicGame {

    private TiledMap map;

    private ArrayList<Squad> squads;

	private Double mapXForTile = 0.0;
	
	private Double mapYForTile = 0.0;

    private MapTile currTile;
    
	private int hovMapX = 0;

    private int hovMapY = 0;
	
    private int hovTileX = 0;

    private int hovTileY = 0;
	
	private int hoverTileId = 0;
    
    private boolean unitPlacementPhase = true;

    private Marine selectedChar;
    
    private boolean ctrlPressed = false;
    
    public UnitPlacementTest()
    {
        super("Unit Placement Test");
    }

    @Override
    public void init(GameContainer arg0)
        throws SlickException
    {
         map = new TiledMap("data/maps/testTileset.tmx");
         XMLPackedSheet sheet = new XMLPackedSheet("data/img/packedTest.png", "data/img/packedTest.png.xml");

         int s = 1;
         String squadString;
         squads = new ArrayList<Squad>();
         do
         {
             String squadName = "squad" + s;
             squadString = map.getMapProperty(squadName, "");

             if(squadString.equals("")) break;

             squads.add(GameUtils.parseSquadString(squadString, sheet));

             s++;
         }while(true);
    }

    @Override
    public void update(GameContainer arg0, int arg1)
        throws SlickException {}

    @Override
    public void render(GameContainer container, Graphics g)
        throws SlickException
    {
        map.render(0, 0);

        if(hoverTileId != 0)
        	g.drawRect(mapXForTile.floatValue(), mapYForTile.floatValue(), map.getTileWidth(), map.getTileHeight());

        //Loop through all characters

        ////Loop through all squads
        for(Squad s : squads) 
        {
        	//marines
        	for(Marine m : s.getMarines()) 
        	{
        		if(m.doRender()) m.draw();
        	}
        	//flamers
        	for(Marine m : s.getFlamers()) 
        	{
        		if(m.doRender()) m.draw();
        	}
        	//sergents
        	for(Marine m : s.getSergents()) 
        	{
        		if(m.doRender()) m.draw();
        	}
        }
    }

    public void mouseReleased(int button, int x, int y)
    {
    	this.currTile = TileMapUtils.getMapTileFromClick(x, y, map);
    	
    	//Squad placement phase
        if(unitPlacementPhase)
        {
            placeMarine(currTile);
        } else {
        	determineCharAtClick();
        }
        
    }

    public void placeMarine(MapTile currTile)
    {
        if(currTile.getId() != -1)
        {
            boolean unitPlaced = false;

            if(true) //Need to check for valid placement tile ID...what that may be
            {
            	for(Squad s : squads) 
                {
            		//marines
                	for(Marine m : s.getMarines()) 
                	{
                		if(m.isPlaced() == false)
                		{
                			m.placeChar(currTile.getMapX(), currTile.getMapY());
                    		unitPlaced = true;
                    		break;
                		}
                	}
                	
                	if(unitPlaced) break;
                	
                	//flamers
                	for(Marine m : s.getFlamers()) 
                	{
                		if(m.isPlaced() == false)
                		{
                			m.placeChar(currTile.getMapX(), currTile.getMapY());
                    		unitPlaced = true;
                    		break;
                		}
                	}
                	
                	if(unitPlaced) break;
                	
                	//sergents
                	for(Marine m : s.getSergents()) 
                	{
                		if(m.isPlaced() == false)
                		{
                			m.placeChar(currTile.getMapX(), currTile.getMapY());
                    		unitPlaced = true;
                    		break;
                		}
                	}
                }   
            }
            
            //We have looped through all squads and units, everyone has been placed, we are done with this phase
            if(unitPlaced == false) 
        	{
        		unitPlacementPhase = false;
        		System.out.println("Unit placement phaser over..");
        	}
        }
    }

    public void determineCharAtClick()
    {
    	//loop through the squads for any character that has those coords
    	for(Squad s : squads)
    	{
    		for(Marine m : s.getAllUnits())
    		{
    			if(m.getX() == currTile.getMapX() && m.getY() == currTile.getMapY())
    			{
    				selectedChar = m;
    				System.out.println("Selected character is: " + m.getName());
    			}
    		}
    	}
    }
    
    public void keyPressed(int key, char c)
    {
		if(selectedChar != null)
		{
			if(key == Input.KEY_LCONTROL || key == Input.KEY_RCONTROL) ctrlPressed = true;
	
	        if(ctrlPressed)
	        {
	            if(key == Input.KEY_LEFT) selectedChar.turnLeft();
	
	            if(key == Input.KEY_RIGHT) selectedChar.turnRight();
	        }
	        else
	        {
	            if(key ==  Input.KEY_LEFT && canMoveX(selectedChar.getX(), selectedChar.getY(), -1))
	            {
	                if(key == Input.KEY_LEFT) selectedChar.setX(selectedChar.getX() - selectedChar.getMoveX()); 
	            }
	
	            if(key == Input.KEY_RIGHT && canMoveX(selectedChar.getX(), selectedChar.getY(), 1))
	            {
	                if(key == Input.KEY_RIGHT) selectedChar.setX(selectedChar.getX() + selectedChar.getMoveX()); 
	            }
	        }
	
	        if(key == Input.KEY_UP && canMoveY(selectedChar.getX(), selectedChar.getY(), -1))
	        {
	            if(key == Input.KEY_UP)selectedChar.setY(selectedChar.getY() - selectedChar.getMoveY()); 
	        }
	
	        if(key == Input.KEY_DOWN && canMoveY(selectedChar.getX(), selectedChar.getY(), 1))
	        {
	            if(key == Input.KEY_DOWN)selectedChar.setY(selectedChar.getY() + selectedChar.getMoveY()); 
	        }
		}

        //if(key == Input.KEY_SPACE) performCharAction();

        if(key == Input.KEY_ESCAPE) System.exit(0);
    }
    
    /**
     * Check the horizontal bounds
     * @param x
     * @param y
     * @return
     */
    public boolean canMoveX(int x, int y, int dir)
    {
        boolean canMove = false;

        do
        {
            int futureXPos = (dir > 0) ? (selectedChar.getX() + selectedChar.getMoveX()) : (selectedChar.getX() - selectedChar.getMoveX());

            System.out.println("Current X pos: " + selectedChar.getX());
            System.out.println("-future X position would be: " + futureXPos);

            //Check if there is a valid tileID
            int futureTileId = TileMapUtils.determineTileIdFromXY(futureXPos, selectedChar.getY(), map);

            if(futureTileId == 0)
            {
                System.out.println("Can't move there, no tile!");
                break;
            }

            //Check if the player can move to the tile or if something is blocking him
            String impassable = map.getTileProperty(futureTileId, "impassable", "");
            if(impassable != "")
            {
                System.out.println("Something is in the way!!");
                break;
            }

            canMove = true;
            break;

        } while(true);

        return canMove;
    }
    
    /**
     * Check the vertical bounds
     * @param x
     * @param y
     * @return
     */
    public boolean canMoveY(int x, int y, int dir)
    {
        boolean canMove = false;
        do
        {
            int futureYPos = (dir > 0) ? (selectedChar.getY() + selectedChar.getMoveY()) : (selectedChar.getY() - selectedChar.getMoveY());

            System.out.println("Current Y pos: " + selectedChar.getY());
            System.out.println("-future Y position would be: " + futureYPos);

            //Check if there is a valid tileID
            int futureTileId = TileMapUtils.determineTileIdFromXY(selectedChar.getX(), futureYPos, map);

            if(futureTileId == 0)
            {
                System.out.println("Can't move there, no tile!");
                break;
            }

            //Check if the player can move to the tile or if something is blocking him
            String impassable = map.getTileProperty(futureTileId, "impassable", "");
            if(impassable != "")
            {
                System.out.println("Something is in the way!!");
                break;
            }

            canMove = true;
            break;

        } while(true);

        return canMove;
    }

    public void keyReleased(int key, char c)
    {
        if(key == Input.KEY_LCONTROL || key == Input.KEY_RCONTROL)
            ctrlPressed = false;
    }
    
    public void mouseMoved(int oldx, int oldy, int newx, int newy)
    {
    	 hovTileX = TileMapUtils.getTileXfromMapX(newx, map);
	     hovTileY = TileMapUtils.getTileYfromMapY(newy, map);
	     
	     hoverTileId = map.getTileId(hovTileX, hovTileY, 0);
	     
	     mapXForTile = new Double(TileMapUtils.getTileXBorderFromMapX(newx, map));
	     mapYForTile = new Double(TileMapUtils.getTileYBorderFromMapY(newy, map));
    }
    

    public static void main(String[] args)
    {
        try {
            AppGameContainer app = new AppGameContainer(new UnitPlacementTest());
            app.setDisplayMode(800, 600, false);
            app.start();
        } catch (SlickException e) {
            e.printStackTrace();
        }
    }
}
